package org.ws.task.model;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

public class NodeMetadata implements Serializable {

    private static final long serialVersionUID = 2706024158149994443L;

    private String id;

    private NodeStatus status = NodeStatus.READY;

    private NodeRole role;

    private String host;

    private Integer port=-1;

    private Date updateTime;

    public void setStatus(NodeStatus status) {
        this.status = status;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getId() {
        return id;
    }

    public NodeStatus getStatus() {
        return status;
    }

    public NodeRole getRole() {
        return role;
    }

    public String getHost() {
        return host;
    }

    public Integer getPort() {
        return port;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public String getAddress(){
        return host+":"+port;
    }

    public boolean isActive(){
        return status == NodeStatus.ACTIVE && port > 0;
    }

    public boolean isLeader(){
        return role == NodeRole.LEADER;
    }

    public static NodeMetadataBuilder builder(){
        return new NodeMetadataBuilder();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NodeMetadata that = (NodeMetadata) o;
        return Objects.equals(id, that.id) &&
                status == that.status &&
                role == that.role &&
                Objects.equals(host, that.host) &&
                Objects.equals(port, that.port);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, status, role, host, port, updateTime);
    }

    @Override
    public String toString() {
        return "NodeMetadata{" +
                "id='" + id + '\'' +
                ", status=" + status +
                ", role=" + role +
                ", host='" + host + '\'' +
                ", port=" + port +
                ", updateTime=" + updateTime +
                '}';
    }


    public static final class NodeMetadataBuilder {
        private String id;
        private NodeStatus status = NodeStatus.READY;
        private NodeRole role = NodeRole.WORKER;
        private String host;
        private Integer port=-1;
        private Date updateTime = new Date();

        private NodeMetadataBuilder() {
        }


        public NodeMetadataBuilder id(String id) {
            this.id = id;
            return this;
        }

        public NodeMetadataBuilder status(NodeStatus status) {
            this.status = status;
            return this;
        }

        public NodeMetadataBuilder role(NodeRole role) {
            this.role = role;
            return this;
        }

        public NodeMetadataBuilder host(String host) {
            this.host = host;
            return this;
        }

        public NodeMetadataBuilder port(Integer port) {
            this.port = port;
            return this;
        }

        public NodeMetadataBuilder updateTime(Date updateTime) {
            this.updateTime = updateTime;
            return this;
        }

        public NodeMetadata build() {
            NodeMetadata nodeMetadata = new NodeMetadata();
            nodeMetadata.setStatus(status);
            nodeMetadata.setPort(port);
            nodeMetadata.setUpdateTime(updateTime);
            nodeMetadata.host = this.host;
            nodeMetadata.role = this.role;
            nodeMetadata.id = this.id;
            return nodeMetadata;
        }
    }
}
